home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / JimmDemos / DemoSource / dview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  7.8 KB  |  346 lines

  1. /* dview.c -- double-buffering through views
  2.  * Copyright (c) 1988, I and I Computing, and Commodore-Amiga, Inc.
  3.  *
  4.  * 
  5.  * Executables based on this information may be used in software
  6.  * for Commodore Amiga computers.  All other rights reserved.
  7.  *
  8.  * This information is provided "as is"; no warranties are made.
  9.  * All use is at your own risk, and no liability or responsibility is assumed.
  10.  */
  11.  
  12. #include "sysall.h"
  13. #include "dview.h"
  14.  
  15. /* 1 <-> 0    */
  16. #define OTHER_ONE( vid ) ( 1 - (vid) )
  17. #define FORBOTH( i )    for ( i = 0; i < 2; ++i)
  18.  
  19. /* shorthand    */
  20. #define ALLOC( S, flags) (AllocMem( (LONG) sizeof (struct S), (LONG) (flags)))
  21. #define FREE( ptr, S) FreeMem( (ptr), (LONG) sizeof (struct S));
  22.  
  23. #define NUMCOLORS    (32)
  24.  
  25. /* allocates and sets up a DoubleView structure based on
  26.  * an existing screen.  Allocates two copies of everything
  27.  * except the screen's bitmap and bitplanes.
  28.  * creates copper lists.
  29.  * returns non-zero if successful
  30.  * assumes graphics.library is open
  31.  */
  32. initDV( dv, screen )
  33. struct DoubleView    *dv;
  34. struct Screen         *screen;
  35. {
  36.     struct View        *vlord;
  37.     struct View        *v;
  38.     struct ViewPort    *vp;
  39.     int                vx;            /* double view index     */
  40.     struct BitMap    *sbitmap;    /* screen's bitmap        */
  41.     struct BitMap    *bmap;
  42.  
  43.     int                depth;
  44.     int                i;
  45.  
  46.     UWORD            colortable[ NUMCOLORS ];    /* screen's colors    */
  47.     int                colorcount;
  48.  
  49.     vlord = ViewAddress();
  50.  
  51.     sbitmap = &screen->BitMap;
  52.     dv->dv_Width = sbitmap->BytesPerRow << 3;
  53.     dv->dv_Height = sbitmap->Rows;
  54.     depth = sbitmap->Depth;
  55.  
  56.     /* get the screen's colors    */
  57.     colorcount = screen->ViewPort.ColorMap->Count;
  58.     if (colorcount > NUMCOLORS) colorcount = NUMCOLORS;
  59.     i = colorcount;
  60.     while ( i-- )
  61.     {
  62.         colortable[ i ] =  GetRGB4( screen->ViewPort.ColorMap, (LONG) i);
  63.     }
  64.  
  65.     /*
  66.      * initialize stuff to make it easy to clean up
  67.      */
  68.     dv->dv_Current = 0;
  69.     dv->dv_RastPorts[ 0 ] =  dv->dv_RastPorts[ 1 ] = NULL;
  70.     dv->dv_Views[ 0 ] =  dv->dv_Views[ 1 ] = NULL;
  71.     dv->dv_Signal = -1;
  72.  
  73.     FORBOTH( vx )
  74.     {
  75.         /*
  76.          * init rastports    
  77.          */
  78.         if (!( dv->dv_RastPorts[ vx ] = ALLOC( RastPort, 0))) goto FAIL;
  79.         InitRastPort( dv->dv_RastPorts[ vx ] );
  80.  
  81.         /*
  82.          * init companion bitmap and planes    
  83.          */
  84.         if ( vx == 1)
  85.         {
  86.             /* clone screen's bitmap    */
  87.             if ( !( bmap =  ALLOC( BitMap, 0))) goto FAIL;
  88.  
  89.             InitBitMap( dv->dv_RastPorts[ vx ]->BitMap = bmap,
  90.                 (LONG) depth, (LONG) dv->dv_Width, (LONG) dv->dv_Height);
  91.  
  92.             for ( i = 0; i < depth; ++i )
  93.             {
  94.                 if (!(bmap->Planes[i] =
  95.                     AllocRaster((LONG) dv->dv_Width, (LONG) dv->dv_Height)))
  96.                 {
  97.                     goto FAIL;
  98.                 }
  99.             }
  100.         }
  101.         else
  102.         {
  103.             /* use screen's bitmap    */
  104.             bmap = dv->dv_RastPorts[ vx ]->BitMap = sbitmap;
  105.         }
  106.  
  107.         /*
  108.          * init views and viewports            
  109.          */
  110.         if (!(v = ALLOC( View, 0 ))) goto FAIL;
  111.         InitView( dv->dv_Views[ vx ] = v );
  112.  
  113.         v->DxOffset = vlord->DxOffset;
  114.         v->DyOffset = vlord->DyOffset;
  115.  
  116.         if (!(v->ViewPort = ALLOC( ViewPort, 0 ))) goto FAIL;
  117.         vp = v->ViewPort;
  118.         InitVPort( vp );
  119.  
  120.         /*
  121.          * init rasinfo, colormap
  122.          */
  123.         if (!(vp->RasInfo = ALLOC( RasInfo, MEMF_CLEAR))) goto FAIL;
  124.         vp->RasInfo->BitMap = bmap;
  125.  
  126.         /* overkill number of colors    */
  127.         if (!(vp->ColorMap = GetColorMap( (LONG) NUMCOLORS )))
  128.         {
  129.             goto FAIL;
  130.         }
  131.  
  132.         /* clone colors    */
  133.         LoadRGB4( vp, colortable, (LONG) colorcount);
  134.  
  135.         /* other viewport init    */
  136.         vp->DWidth = dv->dv_Width;
  137.         vp->DHeight = dv->dv_Height;
  138.         vp->Modes = screen->ViewPort.Modes & ~VP_HIDE;
  139.  
  140.         /*
  141.          * set up user copper list to generate an interrupt
  142.          * on my viewport's last line
  143.          */
  144.         if (!(vp->UCopIns = createUCop( vp->DHeight - 1, vp->DWidth - 1 )))
  145.         {
  146.             goto FAIL;
  147.         }
  148.  
  149.         /*
  150.          * create view                
  151.          */
  152.         MakeVPort( v, vp );
  153.         MrgCop( v );
  154.  
  155.     }    /* end FORBOTH */
  156.  
  157.     /*
  158.      * copy bitmap contents        
  159.      */
  160.     syncDV( dv, 0);
  161.  
  162.     /* install video interrupt handlers    */
  163.     if ( (dv->dv_Signal = AllocSignal( (long) -1 )) == -1) goto FAIL;
  164.  
  165.     dv->dv_SigMask = (long) 1 << dv->dv_Signal;
  166.     printf("SigMask: %lx\n", dv->dv_SigMask );
  167.     installHandlers( dv->dv_Signal );
  168.  
  169.     return 1;
  170.  
  171. FAIL:
  172.     freeDV( dv );
  173.     return 0;
  174. }
  175.  
  176. /* frees everything set up by initDV().  Note that it
  177.  * frees just one set of bitmap and planes.
  178.  * can be used to free partial set
  179.  * WARNING: Be Sure that neither view is current in graphics
  180.  * mind.  Call RethinkDisplay() (needn't do CloseScreen())
  181.  * to reinstall Intuition's View
  182.  */
  183. freeDV( dv )
  184. struct DoubleView    *dv;
  185. {
  186.     int                vx;            /* double view index     */
  187.     struct View        *v;
  188.     struct ViewPort    *vp;
  189.     struct BitMap    *bmap;
  190.     struct RastPort    *rp;
  191.     int                plane;
  192.  
  193.     /* 0 and -1 are both "error" indicators: no clean up    */
  194.     if (dv->dv_Signal != 0 && dv->dv_Signal != -1)
  195.     {
  196.         removeHandlers();
  197.         FreeSignal( (long) dv->dv_Signal );
  198.     }
  199.  
  200.     WaitTOF();        /* be sure coppers and handlers aren't in use    */
  201.  
  202.     FORBOTH( vx )
  203.     {
  204.         /* View hierarchy    */
  205.         if ( v = dv->dv_Views[ vx ] )
  206.         {
  207.             if ( vp = v->ViewPort )
  208.             {
  209.                 if ( vp->ColorMap )
  210.                 {
  211.                     FreeColorMap( vp->ColorMap );
  212.                 }
  213.  
  214.                 if ( vp->RasInfo ) FREE( vp->RasInfo, RasInfo );
  215.  
  216.                 /* free the intermediate copper lists created by MakeVPort    */
  217.                 FreeVPortCopLists( vp );
  218.  
  219.                 FREE( vp, ViewPort );
  220.             }
  221.             /* free user copper list    */
  222.             freeUCop( vp->UCopIns );
  223.  
  224.             /* Free the copper lists created by MrgCop    */
  225.             FreeCprList( v->LOFCprList );
  226.             FreeCprList( v->SHFCprList );
  227.  
  228.             FREE( v, View );
  229.             dv->dv_Views[ vx ] = NULL;        /* and void    */
  230.         }
  231.  
  232.         /* RastPort hierarchy    */
  233.         if ( rp = dv->dv_RastPorts[ vx ] )
  234.         {
  235.             if (vx == 1)        /* only the stuff I allocated    */
  236.             {
  237.                 if ( bmap = rp->BitMap )
  238.                 {
  239.                     plane = bmap->Depth;
  240.                     while ( plane-- )
  241.                     {
  242.                         if ( bmap->Planes[ plane ] )
  243.                         {
  244.                             FreeRaster( bmap->Planes[plane],(LONG)dv->dv_Width,
  245.                                 (LONG) dv->dv_Height);
  246.                         }
  247.                     }
  248.  
  249.                     FREE( bmap, BitMap );
  250.                 }
  251.             }
  252.  
  253.             FREE( rp, RastPort );
  254.             dv->dv_RastPorts[ vx ] = NULL;        /* and void    */
  255.         }
  256.     }
  257. }
  258.  
  259. /* copies buffers from one view buffer 'srcvid' to other */
  260. syncDV( dv, srcvid )
  261. struct DoubleView    *dv;
  262. int                    srcvid;
  263. {
  264.     BltBitMap( dv->dv_RastPorts[ srcvid ]->BitMap, 0L, 0L,
  265.         dv->dv_RastPorts[ OTHER_ONE( srcvid ) ]->BitMap, 0L, 0L,
  266.         (LONG) dv->dv_Width, (LONG) dv->dv_Height, (LONG) 0xc0, (LONG) 0xff, 0L);
  267.  
  268. /* install view indexed by 'vid' ,
  269.  * initiates BOVP mechanism, returns pointer
  270.  * to offscreen rastport
  271.  */
  272. struct RastPort *
  273. selectDV( dv, vid )
  274. struct DoubleView    *dv;
  275. int        vid;
  276. {
  277.     dv->dv_Current = vid;
  278.  
  279.     LoadView( dv->dv_Views[ vid ] );
  280.     SetSignal( 0L, dv->dv_SigMask );    /* clear signal bit    */
  281.     return ( dv->dv_RastPorts[ OTHER_ONE( dv->dv_Current ) ] );
  282. }
  283.  
  284. /* switches displayed view,
  285.  * initiates BOVP mechanism, returns pointer
  286.  * to offscreen rastport
  287.  */
  288. struct RastPort *
  289. swapDV( dv )
  290. struct DoubleView    *dv;
  291. {
  292.     return ( selectDV( dv, OTHER_ONE( dv->dv_Current ) ) );
  293. }
  294.  
  295. /* waits until it safe to render into offscreen buffer */
  296. waitDV( dv )
  297. struct DoubleView    *dv;
  298. {
  299.     Wait( dv->dv_SigMask );
  300.     return;
  301. }
  302.  
  303. /* returns pointer to rastport for current view */
  304. struct RastPort *
  305. onscreenDV( dv )
  306. struct DoubleView    *dv;
  307. {
  308.     return ( dv->dv_RastPorts[ dv->dv_Current ] );
  309. }
  310.  
  311. /* returns pointer to rastport for view currently offscreen */
  312. struct RastPort *
  313. offscreenDV( dv )
  314. struct DoubleView    *dv;
  315. {
  316.     return ( dv->dv_RastPorts[ OTHER_ONE( dv->dv_Current ) ] );
  317. }
  318.  
  319. dumpDV( dv )
  320. struct DoubleView    *dv;
  321. {
  322.     printf("DoubleView at %lx\n", dv);
  323.     printf("current: %d, width/height %d/%d\n",
  324.         dv->dv_Current, dv->dv_Width, dv->dv_Height);
  325.  
  326.     printf("rastports: %lx/%lx\n", dv->dv_RastPorts[0], dv->dv_RastPorts[1]);
  327.  
  328.     printf("views: %lx/%lx\n", dv->dv_Views[0], dv->dv_Views[1]);
  329.     printf("viewports: %lx/%lx\n",
  330.         dv->dv_Views[0]->ViewPort, dv->dv_Views[1]->ViewPort);
  331.     printf("rasinfos %lx/%lx\n",
  332.         dv->dv_Views[0]->ViewPort->RasInfo, dv->dv_Views[1]->ViewPort->RasInfo);
  333.     printf("bitmaps: %lx/%lx\n",
  334.         dv->dv_Views[0]->ViewPort->RasInfo->BitMap,
  335.         dv->dv_Views[1]->ViewPort->RasInfo->BitMap);
  336.  
  337.     printf("rastports: %lx/%lx\n",
  338.         dv->dv_RastPorts[0], dv->dv_RastPorts[1]);
  339.  
  340.     printf("rpbitmaps: %lx/%lx\n", 
  341.         dv->dv_RastPorts[0]->BitMap, dv->dv_RastPorts[1]->BitMap);
  342.  
  343. }
  344.  
  345.